<template>
  <div class="outer">
    <center>
      <div class="dialog">
        <div class="two">
          <div class="img">
            <img :src="require('@/assets/img/47dc19b4b032551d69a151d13b03cde.jpg')" alt="" style="width: 100%" />
          </div>
          <div class="content">
            <div class="title" id="0" style="display: flex; flex-direction: row">
              {{ welcome }}
            </div>
            <div class="icon">
              <div class="copy">
                <svg-icon icon-class="copy" />
                <div style="margin-left: 5px" @click="handleCopy(welcome)">复制</div>
              </div>
            </div>
          </div>
        </div>
        <div v-for="(item, index) in contentArr" :key="index">
          <!-- 用户输出 -->
          <div class="one">
            <span>{{ item.inputtext }}</span>
          </div>

          <!-- ai输出 -->
          <div class="two">
            <div class="img">
              <img :src="require('@/assets/img/47dc19b4b032551d69a151d13b03cde.jpg')" alt="" style="width: 100%" />
            </div>
            <div class="content">
              <VueMarkdown class="title" :source="item.restext">
              </VueMarkdown>
              <div class="icon">
                <div class="copy">
                  <svg-icon icon-class="copy" />
                  <div style="margin-left: 5px" @click="handleCopy(item.restext)">
                    复制
                  </div>
                </div>
                <div class="retry">
                  <svg-icon icon-class="retry" />
                  <div style="margin-left: 5px" @click="doItAgain">
                    再试一次
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </center>
    <div style="display: flex; justify-content: center">
      <div class="input">
        <textarea placeholder="请输入内容" id="inputcon" class="prompt" v-model="prompt" @keyup.enter="send"></textarea>
        <div class="bottom">
          <div class="right">
            <!-- <div class="send" id="sending" @click="send">
            <svg-icon icon-name="unsend" class="sendno"></svg-icon>
            <svg-icon icon-name="send" class="truesend"></svg-icon>
          </div> -->
            <el-button type="primary" :disabled="isContent" :loading="isSend" icon="el-icon-arrow-right"
              style="padding: 8px; border-radius: 50%" @click="send" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>



<script>
import { checkActivityStatus, getMyJoinActivity } from "../../api/activity";
import VueMarkdown from "vue-markdown";
import Cookies from 'js-cookie'
export default {
  components: {
    VueMarkdown,
  },
  data() {
    return {
      welcome:
        "欢迎来到智能聊天室!请问有什么可以帮助你的？如果你有任何问题或者需要建议，请随时告诉我。",
      prompt: "",
      receive: "",
      isContent: true,
      isSend: false,
      contentArr: [], //内容存储数组
      content: [], //传输后端数组
    };
  },
  watch: {
    prompt: function (newVal) {
      if (this.prompt) {
        this.isContent = false;
      } else {
        this.isContent = true;
      }
    },
  },
  methods: {
    //复制功能
    copyDomText() {
      const titleElement = document.getElementById("0");
      if (titleElement) {
        const text = titleElement.innerText;
        console.log(text);
        navigator.clipboard
          .writeText(text)
          .then(() => {
            ElMessage({
              message: "复制成功",
              type: "success",
            });
          })
          .catch((err) => {
            ElMessage({
              message: "复制失败",
              type: "error",
            });
          });
      }
    },
    // 一键复制
    handleCopy(str) {
      this.$copyText(str)
        .then(() => {
          this.$message.success("复制成功");
        })
        .catch(() => {
          this.$message.success("复制失败");
        });
    },
    //刷新功能
    doItAgain() {
      this.prompt = this.contentArr[this.contentArr.length - 1].inputtext;
      this.contentArr.pop();
      this.isSend = false;
      this.send();
    },
    async send() {
      if (!this.prompt) return;
      this.isSend = true;

      // 初始化新条目
      const newItem = {
        inputtext: this.prompt,
        restext: ""
      };
      this.contentArr.push(newItem);
      this.content.push(this.prompt);

      try {
        const response = await fetch("http://106.52.100.34:8222/cmsservice/cms-ai/getReply", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            "token": Cookies.get("token")
          },
          body: JSON.stringify({
            "messages": this.content,
            "model": "kimi",
            // "scene": "activityCreator"
            "scene": "chatter"
          }),
        });

        this.prompt = "";
        if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);

        const reader = response.body.getReader();
        const decoder = new TextDecoder();
        const lastItem = this.contentArr[this.contentArr.length - 1];

        // 新增状态管理变量
        let buffer = "";
        let combinedContent = ""; // 用于最终拼接的字符串
        let braceDepth = 0;
        let jsonStartIndex = -1;

        const processJSON = (jsonStr) => {
          try {
            const jsonObj = JSON.parse(jsonStr);
            if (jsonObj.content !== undefined) { // 确保content字段存在
              const content = jsonObj.content || ""; // 处理空内容
              combinedContent += content;
              lastItem.restext += content; // 实时更新显示
            }
          } catch (e) {
            console.error("JSON解析失败:", e);
          }
        };

        // 流处理主循环
        while (true) {
          const { done, value } = await reader.read();
          if (done) {
            this.isSend = false;
            // 处理最后可能残留的JSON
            if (braceDepth > 0) {
              console.warn("不完整的JSON结尾:", buffer);
            }
            break;
          }

          buffer += decoder.decode(value, { stream: true });

          // 状态机解析
          for (let i = 0; i < buffer.length; i++) {
            const char = buffer[i];
            if (char === '{') {
              if (braceDepth === 0) jsonStartIndex = i;
              braceDepth++;
            } else if (char === '}') {
              braceDepth--;
              if (braceDepth === 0 && jsonStartIndex !== -1) {
                const jsonStr = buffer.slice(jsonStartIndex, i + 1);
                processJSON(jsonStr);
                buffer = buffer.slice(i + 1); // 移除已处理部分
                i = -1; // 重置循环索引
                jsonStartIndex = -1;
              }
            }
          }

          // 触发UI更新（优化性能）
          await new Promise(r => requestAnimationFrame(r));
        }

        // 最终处理
        this.content.push(combinedContent);
        // console.log("完整拼接内容:", combinedContent);
      } catch (error) {
        this.isSend = false;
        console.error("请求失败:", error);
        alert("请求失败，请检查网络或重试！");
      }
    },
    handleResponse(response) {
      finalContent += response.content;

      // 如果 isEnd 为 true，表示拼接完成
      if (response.isEnd) {
        console.log("拼接完成:", finalContent);
      }
    }
  },
  created() { },
  mounted() { },
};
</script>


<style scoped>
/* 基础重置 */
* {
  box-sizing: border-box;
  font-family: 'Helvetica Neue', Arial, sans-serif;
}

::v-deep p,
::v-deep li {
  text-align: left;
}

.outer {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* 对话框容器 */
.dialog {
  flex: 1;
  overflow-y: auto;
  padding: 20px 0;
  margin-bottom: 100px;
}

/* 用户消息 */
.one {
  display: flex;
  justify-content: flex-end;
  margin: 20px 0;
}

.one span {
  background: #409EFF;
  color: white;
  padding: 15px 25px;
  border-radius: 15px 15px 0 15px;
  max-width: 80%;
  line-height: 1.6;
  box-shadow: 0 3px 12px rgba(64, 158, 255, 0.15);
  transition: all 0.3s;
}

/* AI回复 */
.two {
  display: flex;
  gap: 15px;
  margin: 20px 0;
}

.two .img {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  border: 2px solid #fff;
  box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.2);
  position: relative;
}

.two .img img {
    position: absolute;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
  }

.two .content {
  background: #f8f9fa;
  border-radius: 15px;
  padding: 15px 20px;
  flex: 1;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.06);
  position: relative;
}

/* Markdown内容样式 */
.title {
  color: #2c3e50;
  line-height: 1.7;
  font-size: 0.95rem;
}

.title>>>pre {
  background: #f0f4f9;
  padding: 15px;
  border-radius: 8px;
  overflow-x: auto;
}

.title>>>code {
  font-family: 'Source Code Pro', monospace;
  font-size: 0.85rem;
}

/* 操作按钮 */
.icon {
  display: flex;
  gap: 15px;
  margin-top: 15px;
}

.copy,
.retry {
  display: flex;
  align-items: center;
  font-size: 0.85rem;
  color: #909399;
  padding: 6px 12px;
  border-radius: 15px;
  transition: all 0.3s;
  cursor: pointer;
}

.copy:hover,
.retry:hover {
  background: rgba(64, 158, 255, 0.1);
  color: #409EFF;
}

/* 输入框区域 */
.input {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  width: calc(100% - 40px);
  max-width: 1200px;
  background: white;
  border-radius: 15px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08);
  padding: 15px;
}

.prompt {
  width: 100%;
  min-height: 100px;
  border: none;
  resize: none;
  font-size: 1rem;
  line-height: 1.6;
  padding-right: 60px;
}

.prompt:focus {
  outline: none;
}

/* 发送按钮 */
.bottom {
  position: absolute;
  right: 15px;
  bottom: 15px;
}

::v-deep .el-button--primary {
  background: linear-gradient(135deg, #409EFF, #3375b9);
  border: none;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  transition: all 0.3s;
}

::v-deep .el-button--primary:hover {
  transform: scale(1.1);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
}

/* 滚动条美化 */
::-webkit-scrollbar {
  width: 8px;
}

::-webkit-scrollbar-track {
  background: #f8f9fa;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb {
  background: #c0c4cc;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: #909399;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .outer {
    padding: 10px;
  }

  .two .content {
    padding: 12px 15px;
  }

  .one span {
    max-width: 90%;
    padding: 12px 20px;
  }

  .input {
    width: calc(100% - 20px);
    bottom: 10px;
  }

  .prompt {
    min-height: 80px;
    font-size: 0.9rem;
  }

  .two .img {
    width: 32px;
    height: 32px;
    position: relative;
  }
}
</style>
